package v1;// DBusMonitorServer.java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DBusMonitorServer {
    private Process monitorProcess;
    private boolean isMonitoring = false;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final WiFiManager wifiManager = new WiFiManager();
    private final BluetoothSender bluetoothSender = new BluetoothSender();

    private String lastBluetoothDevicePath = null;

    public void startSystemBusMonitoring() {
        try {
            System.out.println("启动 D-Bus 监控服务器...");

            // 启动 dbus-monitor 进程
            ProcessBuilder pb = new ProcessBuilder(
                    "dbus-monitor",
                    "--system",
                    "type='signal',interface='org.freedesktop.DBus.Properties'"
            );

//            monitorProcess = pb.start();
            isMonitoring = true;

            System.out.println("dbus-monitor 进程已启动");

            // 在单独线程中读取输出
            executor.submit(() -> {
                readMonitorOutput();
            });

            // 保持主线程运行
            while (isMonitoring) {
                Thread.sleep(1000);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void readMonitorOutput() {
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(System.in))) {

            String line;
            StringBuilder signalBuffer = new StringBuilder();
            boolean inSignal = false;

            while ((line = reader.readLine()) != null && isMonitoring) {
                System.out.println("监听到数据:" + line);
                // 检测信号开始
                if (!inSignal && line.startsWith("signal ")) {
                    inSignal = true;
                    signalBuffer.setLength(0);
                    signalBuffer.append(line).append("\n");
                }
                // 检测信号结束（空行或下一个信号开始）
                else if (inSignal && (line.trim().isEmpty() || line.startsWith("signal "))) {
                    processSignal(signalBuffer.toString());
                    signalBuffer.setLength(0);
                    if (line.startsWith("signal ")) {
                        signalBuffer.append(line).append("\n");
                    } else {
                        inSignal = false;
                    }
                } else if (inSignal) {
                    signalBuffer.append(line).append("\n");
                }

                System.out.println(signalBuffer.toString());
            }

        } catch (Exception e) {
            if (isMonitoring) { // 只在正常监控时报告错误
                System.err.println("读取监控输出时出错: " + e.getMessage());
            }
        }
    }

    public void processSignal(String signalText) {
        try {
            System.out.println("=== 解析到信号 ===");
            System.out.println(signalText);

            // 提取信号信息
            String path = extractPath(signalText);
            String interfaceName = extractInterface(signalText);
            String member = extractMember(signalText);

            System.out.println("解析结果:");
            System.out.println("  路径: " + path);
            System.out.println("  接口: " + interfaceName);
            System.out.println("  成员: " + member);

            // 处理 PropertiesChanged 信号
            if ("PropertiesChanged".equals(member) &&
                    "org.freedesktop.DBus.Properties".equals(interfaceName)) {
                handlePropertiesChanged(signalText, path);
            }

            System.out.println("========================================");

        } catch (Exception e) {
            System.err.println("处理信号时出错: " + e.getMessage());
        }
    }

    private String extractPath(String signalText) {
        Pattern pattern = Pattern.compile("path=([^;]+)");
        Matcher matcher = pattern.matcher(signalText);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return null;
    }

    private String extractInterface(String signalText) {
        Pattern pattern = Pattern.compile("interface=([^;]+)");
        Matcher matcher = pattern.matcher(signalText);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return null;
    }

    private String extractMember(String signalText) {
        Pattern pattern = Pattern.compile("member=([^;\n]+)");
        Matcher matcher = pattern.matcher(signalText);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return null;
    }

    private void handlePropertiesChanged(String signalText, String path) {
        System.out.println(">>> 处理 PropertiesChanged 信号");

        // 保存蓝牙设备路径
        if (path != null && path.contains("/org/bluez/hci") && path.contains("/dev_")) {
            lastBluetoothDevicePath = path;
            System.out.println(">>> 保存蓝牙设备路径: " + lastBluetoothDevicePath);
        }

        // 提取属性变化内容
        extractAndProcessProperties(signalText);
    }

    private void extractAndProcessProperties(String signalText) {
        try {
            // 简单的属性提取（可以根据需要增强）
            if (signalText.contains("Alias") || signalText.contains("WIFI") || signalText.contains("SSID")) {
                System.out.println(">>> 发现可能包含WiFi指令的属性");

                // 提取字符串值
                Pattern stringPattern = Pattern.compile("string \"([^\"]+)\"");
                Matcher matcher = stringPattern.matcher(signalText);

                while (matcher.find()) {
                    String value = matcher.group(1);
                    System.out.println("  提取到字符串: " + value);

                    if (value.contains("WIFI:") || value.contains("SSID=")) {
                        System.out.println(">>> 发现WiFi指令: " + value);
                        processWifiCommand(value);
                    }
                }
            }

        } catch (Exception e) {
            System.err.println("提取属性时出错: " + e.getMessage());
        }
    }

    private void extractByteArrayData(String signalText) {
        try {
            // 提取字节值
            Pattern bytePattern = Pattern.compile("byte (0x[0-9a-fA-F]+)");
            Matcher matcher = bytePattern.matcher(signalText);

            StringBuilder hexData = new StringBuilder();
            while (matcher.find()) {
                String hexByte = matcher.group(1);
                hexData.append(hexByte).append(" ");
            }

            if (hexData.length() > 0) {
                System.out.println("  字节数据: " + hexData.toString());

                // 转换为字符串
                String decoded = hexToAscii(hexData.toString());
                System.out.println("  解码为: " + decoded);

                if (decoded.contains("WIFI") || decoded.contains("SSID")) {
                    System.out.println(">>> 在字节数据中发现WiFi指令: " + decoded);
                    processWifiCommand(decoded);
                }
            }

        } catch (Exception e) {
            System.err.println("提取字节数据时出错: " + e.getMessage());
        }
    }

    private String hexToAscii(String hexStr) {
        try {
            StringBuilder output = new StringBuilder();
            String[] hexBytes = hexStr.trim().split(" ");

            for (String hexByte : hexBytes) {
                if (hexByte.startsWith("0x")) {
                    int decimal = Integer.parseInt(hexByte.substring(2), 16);
                    if (decimal >= 32 && decimal <= 126) { // 可打印ASCII字符
                        output.append((char) decimal);
                    }
                }
            }

            return output.toString();
        } catch (Exception e) {
            return "无法解码";
        }
    }

    private void handleInterfacesAdded(String signalText, String path) {
        System.out.println(">>> 处理 InterfacesAdded 信号");
        System.out.println("  对象路径: " + path);

        if (path != null && path.contains("/org/bluez/hci") && path.contains("/dev_")) {
            lastBluetoothDevicePath = path;
            System.out.println(">>> 新蓝牙设备发现: " + lastBluetoothDevicePath);
        }
    }

    private void handleInterfacesRemoved(String signalText, String path) {
        System.out.println(">>> 处理 InterfacesRemoved 信号");
        System.out.println("  对象路径: " + path);

        if (path != null && path.equals(lastBluetoothDevicePath)) {
            System.out.println(">>> 当前设备已断开: " + lastBluetoothDevicePath);
            lastBluetoothDevicePath = null;
        }
    }

    private void processWifiCommand(String command) {
        String originalDevicePath = lastBluetoothDevicePath;
        // 在单独线程中处理WiFi连接，避免阻塞信号处理
        new Thread(() -> {
            try {
                System.out.println("开始处理WiFi连接指令: " + command);

                // 解析 WiFi 配置
                WiFiConfig config = parseWifiConfig(command);
                if (config != null) {
                    // 先发送"正在连接"状态
                    bluetoothSender.sendWifiStatus(originalDevicePath, "CONNECTING", "正在连接WiFi: " + config.ssid);

                    // 连接 WiFi
                    boolean success = wifiManager.connectToWifi(config);

                    // 发送连接结果回蓝牙设备
                    sendWifiResultToBluetooth(success, config.ssid, originalDevicePath);
                } else {
                    // 解析失败
                    bluetoothSender.sendWifiStatus(originalDevicePath, "ERROR", "无法解析WiFi配置");
                }

            } catch (Exception e) {
                System.err.println("处理WiFi指令时出错: " + e.getMessage());
                bluetoothSender.sendWifiStatus(originalDevicePath, "ERROR", "处理失败: " + e.getMessage());
            }
        }).start();
    }

    private WiFiConfig parseWifiConfig(String command) {
        try {
            String[] parts = command.split("[:=,]");
            String ssid = null;
            String password = null;

            for (int i = 0; i < parts.length; i++) {
                if ("SSID".equalsIgnoreCase(parts[i]) && i + 1 < parts.length) {
                    ssid = parts[i + 1];
                } else if ("PASSWORD".equalsIgnoreCase(parts[i]) && i + 1 < parts.length) {
                    password = parts[i + 1];
                } else if ("PASS".equalsIgnoreCase(parts[i]) && i + 1 < parts.length) {
                    password = parts[i + 1];
                } else if (parts[i].contains("WIFI") && i + 1 < parts.length) {
                    ssid = parts[1];
                    password = parts[2];
                }
            }

            if (ssid != null && !ssid.trim().isEmpty()) {
                return new WiFiConfig(ssid.trim(), password != null ? password.trim() : "");
            }
        } catch (Exception e) {
            System.err.println("解析WiFi配置失败: " + e.getMessage());
        }
        return null;
    }

    private void sendWifiResultToBluetooth(boolean success, String ssid, String devicePath) {
        try {
            String status = success ? "CONNECTED" : "FAILED";
            String message = success ?
                    "WiFi连接成功: " + ssid :
                    "WiFi连接失败: " + ssid;

            System.out.println("WiFi连接结果: " + message);

            if (devicePath != null) {
                bluetoothSender.sendWifiStatus(devicePath, status, message);
            }

        } catch (Exception e) {
            System.err.println("发送WiFi结果失败: " + e.getMessage());
        }
    }

    public void stopMonitoring() {
        isMonitoring = false;
        executor.shutdown();

        if (monitorProcess != null) {
            monitorProcess.destroy();
            System.out.println("已停止 dbus-monitor 进程");
        }
    }

    public static void main(String[] args) {
        DBusMonitorServer server = new DBusMonitorServer();

//        server.processSignal("signal time=1761639242.716076 sender=:1.338 -> destination=(null destination) serial=2 path=/org/bluez/hci0/dev_11_22_33_44_55_66; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged\n" +
//                "   string \"org.bluez.Device1\"\n" +
//                "   string \"WIFI:MyHomeNetwork:myPassword123\"");


        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("正在关闭D-Bus监控服务器...");
            server.stopMonitoring();
        }));

        server.startSystemBusMonitoring();
    }
}